package pe.com.hermes.hermetic.negocio.serviceimpl;

import pe.com.hermes.hermetic.beans.BillRecBean;
import pe.com.hermes.hermetic.beans.BillRecCntaBean;
import pe.com.hermes.hermetic.beans.ConfBean;
import pe.com.hermes.hermetic.beans.CorporacionBean;
import pe.com.hermes.hermetic.beans.TiposBean;
import pe.com.hermes.hermetic.beans.User;
import pe.com.hermes.hermetic.beans.UsuCodBancoBean;
import pe.com.hermes.hermetic.modelo.dao.TiposDAO;
import pe.com.hermes.hermetic.negocio.service.TablService;

import pe.com.hermes.hermetic.negocio.ultil.CodCntaComparator;
import pe.com.hermes.hermetic.negocio.ultil.Util;

import java.sql.SQLException;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import java.util.Map;

import java.util.SortedMap;

import java.util.TreeMap;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;

import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;

import org.apache.log4j.Logger;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.MailException;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

import pe.com.hermes.hermetic.beans.EmpleadoBean;
import pe.com.hermes.hermetic.beans.ResponsableBean;
import pe.com.hermes.hermetic.beans.UsersNivConfBean;
import pe.com.hermes.hermetic.exception.NiveAutoNotFoundException;
import pe.com.hermes.hermetic.exception.TooManyNiveAutoByUsuaException;
import pe.com.hermes.unidadesnegocio.comercial.entities.TarjetaEntity;

@Service
public class TablServiceImpl implements TablService{
  protected final static Logger logger = Logger.getLogger(TablServiceImpl.class);
    @Autowired
    private TiposDAO tiposDAO;
    @Autowired
    private JavaMailSenderImpl mailSender;
    public int inseCateConf(String desCate){
        return tiposDAO.inseCateConf(desCate);
    }
    public List getListConfiParamByCateAndSubCate(String codCliente,String codSucursal,String codCate,String codSubCate){
        return tiposDAO.getListConfiParamByCateAndSubCate(codCliente,codSucursal,codCate,codSubCate);
    }
    public int inseConfParamClie(ConfBean confBean){
        return tiposDAO.inseConfParamClie(confBean);
    }
    public int modiConfParamClie(ConfBean confBean){
        return tiposDAO.modiConfParamClie(confBean);
    }
    public List getListTipoPuntBillRecont(){
        List listTipoPuntBillRecont = new ArrayList();
        TiposBean tipoBean = new TiposBean();
        tipoBean.setCodigo("1");
        tipoBean.setDescripcion("Agencias");
        listTipoPuntBillRecont.add(tipoBean);
        tipoBean = new TiposBean();
        tipoBean.setCodigo("11");
        tipoBean.setDescripcion("ATM");
        listTipoPuntBillRecont.add(tipoBean);
        tipoBean = new TiposBean();
        tipoBean.setCodigo("5");
        tipoBean.setDescripcion("Clientes");
        listTipoPuntBillRecont.add(tipoBean);
        return listTipoPuntBillRecont; 
    }
    public List getListTipoCSBillRecont(){
        List listTipoCS = new ArrayList();
        TiposBean tipoBean = new TiposBean();
        tipoBean.setCodigo("1");
        tipoBean.setDescripcion("Normal");
        listTipoCS.add(tipoBean);
        tipoBean = new TiposBean();
        tipoBean.setCodigo("3");
        tipoBean.setDescripcion("Interno");
        listTipoCS.add(tipoBean);        
        return listTipoCS; 
    }
    public List getListTipoRepoBillRecont(){
        List listTipoRepo = new ArrayList();
        TiposBean tipoBean = new TiposBean();
        tipoBean.setCodigo("1");
        tipoBean.setDescripcion("Detallado");
        listTipoRepo.add(tipoBean);
        tipoBean = new TiposBean();
        tipoBean.setCodigo("2");
        tipoBean.setDescripcion("Por Cuenta");
        listTipoRepo.add(tipoBean);  
        tipoBean = new TiposBean();
        tipoBean.setCodigo("3");
        tipoBean.setDescripcion("Por Punto");
        listTipoRepo.add(tipoBean);  
        tipoBean = new TiposBean();
        tipoBean.setCodigo("4");
        tipoBean.setDescripcion("Por Denominacion");
        listTipoRepo.add(tipoBean);  
        return listTipoRepo; 
    }
    public List getListTipoOrigBillRecont(){
        List listTipoCS = new ArrayList();
        TiposBean tipoBean = new TiposBean();
        tipoBean.setCodigo("1");
        tipoBean.setDescripcion("Recojos");
        listTipoCS.add(tipoBean);
        tipoBean = new TiposBean();
        tipoBean.setCodigo("2");
        tipoBean.setDescripcion("Envios");
        listTipoCS.add(tipoBean);
        return listTipoCS; 
    }
    public List getListBillRecCnta(List listBillRecoDetallado){
        Map map = new HashMap();
        for(Object object:listBillRecoDetallado){
            BillRecCntaBean bean = Util.instanceBillRecCntaBean((BillRecBean)object);
            if(map.containsKey(bean.getIdGroupByCnta())){
                bean.addAmmounts((BillRecCntaBean)map.get(bean.getIdGroupByCnta()));
                map.remove(bean.getIdGroupByCnta());
            }
            map.put(bean.getIdGroupByCnta(),bean);
        }
        return new ArrayList(map.values());
    }
    public Map getMapBillRecCntaSummary(List listBillRecoDetallado){
        Map map = new HashMap();
        Map mapJR = new HashMap();
        Collections.sort(listBillRecoDetallado,new CodCntaComparator());
        for(Object object:listBillRecoDetallado){
            BillRecCntaBean bean = Util.instanceBillRecCntaBean((BillRecBean)object);
            if(map.containsKey(bean.getIdGroupCntaSummary())){
                bean.addAmmounts((BillRecCntaBean)map.get(bean.getIdGroupCntaSummary()));
                map.remove(bean.getIdGroupCntaSummary());
            }
            map.put(bean.getIdGroupCntaSummary(),bean);
        }
        SortedMap sortedData = new TreeMap(map);
        String codCnta = null;
        int count = 0;
        List listBillRecoCntaSummaryTemp = new ArrayList();
        Iterator it = sortedData.entrySet().iterator();
        while(it.hasNext()){
            Map.Entry mapEntry = (Map.Entry)it.next();
            if(count==0){
                codCnta = mapEntry.getKey().toString().split("-")[0];
                listBillRecoCntaSummaryTemp.add(mapEntry.getValue());
            }            
            else{
                if(mapEntry.getKey().toString().split("-")[0].equals(codCnta)){
                    listBillRecoCntaSummaryTemp.add(mapEntry.getValue());
                    if(!it.hasNext())
                        mapJR.put(codCnta,new JRBeanCollectionDataSource( listBillRecoCntaSummaryTemp));
                }
                else{
                    mapJR.put(codCnta,new JRBeanCollectionDataSource( listBillRecoCntaSummaryTemp));
                    codCnta = mapEntry.getKey().toString().split("-")[0];
                    listBillRecoCntaSummaryTemp = new ArrayList();
                    listBillRecoCntaSummaryTemp.add(mapEntry.getValue());
                }
            }
            count++;
        }
        return mapJR;
    }
    public List getListBillRecoByPunt(List listBillRecoDetallado){
        Map map = new HashMap();
        for(Object object:listBillRecoDetallado){
            BillRecCntaBean bean = Util.instanceBillRecCntaBean((BillRecBean)object);
            if(map.containsKey(bean.getIdGroupByPunt())){
                bean.addAmmounts((BillRecCntaBean)map.get(bean.getIdGroupByPunt()));
                map.remove(bean.getIdGroupByPunt());
            }
            map.put(bean.getIdGroupByPunt(),bean);
        }
        return new ArrayList(map.values());
    }
    public List getListBillRecoByDenominacion(List listBillRecoDetallado){
        Map map = new HashMap();
        for(Object object:listBillRecoDetallado){
            BillRecCntaBean bean = Util.instanceBillRecCntaBean((BillRecBean)object);
            if(map.containsKey(bean.getIdGroupByDenominacion())){
                bean.addAmmounts((BillRecCntaBean)map.get(bean.getIdGroupByDenominacion()));
                map.remove(bean.getIdGroupByDenominacion());
            }
            map.put(bean.getIdGroupByDenominacion(),bean);
        }
        return new ArrayList(map.values());
    }
    public Map getMapBillRecDetaSummary(List listBillRecoDetallado){
        Map map = new HashMap();
        Map mapJR = new HashMap();
        for(Object object:listBillRecoDetallado){
            BillRecCntaBean bean = Util.instanceBillRecCntaBean((BillRecBean)object);
            if(map.containsKey(bean.getIdGroupDetaSummary())){
                bean.addAmmounts((BillRecCntaBean)map.get(bean.getIdGroupDetaSummary()));
                map.remove(bean.getIdGroupDetaSummary());
            }
            map.put(bean.getIdGroupDetaSummary(),bean);
        }
        SortedMap sortedData = new TreeMap(map);
        String detaKey = null;
        int count = 0;
        List listBillRecoDetaSummaryTemp = new ArrayList();
        Iterator it = sortedData.entrySet().iterator();
        while(it.hasNext()){
            Map.Entry mapEntry = (Map.Entry)it.next();
            if(count==0){
                detaKey = mapEntry.getKey().toString().split("-")[0];
                listBillRecoDetaSummaryTemp.add(mapEntry.getValue());
            }            
            else{
                if(mapEntry.getKey().toString().split("-")[0].equals(detaKey)){
                    listBillRecoDetaSummaryTemp.add(mapEntry.getValue());
                    if(!it.hasNext())
                        mapJR.put(detaKey,new JRBeanCollectionDataSource( listBillRecoDetaSummaryTemp));
                }
                else{
                    mapJR.put(detaKey,new JRBeanCollectionDataSource( listBillRecoDetaSummaryTemp));
                    detaKey = mapEntry.getKey().toString().split("-")[0];
                    listBillRecoDetaSummaryTemp = new ArrayList();
                    listBillRecoDetaSummaryTemp.add(mapEntry.getValue());
                }
            }
            count++;
        }
        return mapJR;
    }
    public List getListBillRecoDetallado(List listBillRecoDetallado){
        List _listBillRecoDetallado = new ArrayList();
        for(Object object:listBillRecoDetallado){
            BillRecCntaBean bean = Util.instanceBillRecCntaBean((BillRecBean)object);
            _listBillRecoDetallado.add(bean);
        }
        return _listBillRecoDetallado;
    }
    public String getSucuFromPunt(String codPunt){
      return tiposDAO.getSucuFromPunt(codPunt);
    }
    public int getTiempoTrancurrido(String date){
        return tiposDAO.getTiempoTrancurrido(date);
    }
    public User getUserByName(String username){
        return tiposDAO.getUserByName(username);
    }
    public List getClieByUser(String usuWeb) throws SQLException{
        return tiposDAO.getClieByUser(usuWeb);
    }
    public Collection getRolesByPerf(String codPerf,String codModu){
        return tiposDAO.getRolesByPerf(codPerf,codModu);
    }

    public void setTiposDAO(TiposDAO tiposDAO) {
        this.tiposDAO = tiposDAO;
    }
    public String getPerfByUsernameAndCodRazoSoci(String usuWeb,int codRazoSoci){
        return tiposDAO.getPerfByUsernameAndCodRazoSoci(usuWeb,codRazoSoci);
    }
    public String getUrlModu(String codModu){
        return tiposDAO.getUrlModu(codModu);
    }

    public boolean isValidSucuByCntaAndTipUnidMone(int codClie, int codCnta, int tipUnidMone, int codSucuHtb){
        return tiposDAO.isValidSucuByCntaAndTipUnidMone(codClie,codCnta,tipUnidMone,codSucuHtb);
    }
    public List getListClieAlertBove(){
        return tiposDAO.getListClieAlertBove();
    }
    public List getListUsuaClie(int codClie){
        return tiposDAO.getListUsuaClie(codClie);
    }
    public int inseConfMailClie(String usuWeb,String codAlert,String usuWebModi,String nomComp){
        return tiposDAO.inseConfMailClie(usuWeb,codAlert,usuWebModi,nomComp);
    }
    public int modiConfMailClie(String usuWeb,String codAlert,String usuWebModi,String nomComp){
        return tiposDAO.modiConfMailClie(usuWeb,codAlert,usuWebModi,nomComp);
    }
    public int delConfMailClie(String usuWeb,String codAlert){
        return tiposDAO.delConfMailClie(usuWeb,codAlert);
    }
    public List getListConfMailClie(int codClie, String codAlert){
        return tiposDAO.getListConfMailClie(codClie,codAlert);
    }
   
   public List<TiposBean> getListPrioAtm(int codClie,int codSucuHtb, int codPunt,String fecAten) throws Exception{
      return tiposDAO.getListPrioAtm(codClie, codSucuHtb, codPunt, fecAten);
  } 
  
  public void sendMail(String remitente,Collection<String> destinatarios,String replyTo, String asunto,String textMessage) {
      if(remitente==null||destinatarios==null||destinatarios.isEmpty()||textMessage==null){
        logger.info("verifique que exista los siguientes datos: @Remitente, @destinatarios y @message");
        return;
      }
      MimeMessage[] mailMessageArray = new MimeMessage[destinatarios.size()];
      int i = 0;      
      for(String destinatario:destinatarios){          
          try {
                MimeMessage message = mailSender.createMimeMessage();
                MimeMessageHelper mailMessage = new MimeMessageHelper(message);
                mailMessage.setTo(destinatario);
                mailMessage.setReplyTo(replyTo);
                mailMessage.setFrom(remitente);
                mailMessage.setSubject(asunto);
                mailMessage.setText(textMessage, true);
                mailMessageArray[i] = message;
            } catch (MessagingException me) {
                // TODO: Add catch code
                me.printStackTrace();
            }
          i++;
      }
      try {
            mailSender.send(mailMessageArray);
      } catch (MailException me) {
          // TODO: Add catch code
          me.printStackTrace();
          logger.error(me);
      } catch (Exception e) {
          // TODO: Add catch code
          e.printStackTrace();
          logger.error(e);
      }
  }
  public List<TarjetaEntity> getListTjtasRetenidas(int codClie, String codSucuHtb,String fecEmisDsde,String fecEmisHsta){
    return tiposDAO.getListTjtasRetenidas(codClie, codSucuHtb, fecEmisDsde, fecEmisHsta);
  }
  public EmpleadoBean getEmplByPuesto(String codPuesto){
      return tiposDAO.getEmplByPuesto(codPuesto);
  }
  public List<String> getListClieByParam(String codCate,String codSubCate){
    return tiposDAO.getListClieByParam(codCate, codSubCate);
  }

  public List<ConfBean> getListNiveles(int codCli, String codPro) throws Exception{
      return tiposDAO.getListNiveles(codCli, codPro);
  }
  public List getListLogConfNiv(String codClie, String tipDocu, String numPedi, String codSeri){
    return tiposDAO.getListLogConfNiv(codClie, tipDocu, numPedi, codSeri);
  }
  
  public List getFechaPublicacion(String opcion, String codClie, String listCodSucu) {
      return tiposDAO.getFechaPublicacion(opcion, codClie, listCodSucu);
  }
  
    public List getListEstadosGeneral(String codEstado) {
        return tiposDAO.getListEstadosGeneral(codEstado);
    }
    
    public String getDesEstado(String codEstado) {
        return tiposDAO.getEstado(codEstado);
    }
    
    
    public String getRazSocial(String usuWeb, int codRazoSoci) {
      return tiposDAO.getRazSocial(usuWeb,codRazoSoci);
    }
    
    public CorporacionBean getCorporacionUsu(String usuWeb, int codRazoSoci) {
        return tiposDAO.getCorporacionUsu(usuWeb,codRazoSoci);
    }

    public UsuCodBancoBean getUsuCodBanco(int codRazoSoci,String codSucu) {
      return tiposDAO.getUsuCodBanco(codRazoSoci, codSucu);
    }

    public UsuCodBancoBean getUsuCodBancoCorp(int codCorp,String codSucu) {
      return tiposDAO.getUsuCodBancoCorp(codCorp, codSucu);
    }

    public int getTipClie(String codClie) {
      return tiposDAO.getTipClie(codClie);
    }

    public List getTiposDinamico(int codGrupTipo, int indTipo, String campo) {
        return tiposDAO.getTiposDinamico(codGrupTipo, indTipo, campo);
    }

    public String getSeriDocu(String tipDocu, String codSucuHtb) {
        return tiposDAO.getSeriDocu(tipDocu, codSucuHtb);
    }


}
